/*  Copyright (C) 2012 Vladimir M. <mlvl.jr@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; by version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

import QtQuick 2.0

Item {
    id: root

    signal alarm

    width: 400
    height: 400

    property real maxSizeForCanvasItems: 300

    property bool secondHandVisible: true

    property bool timerMode: false
    property bool timerPaused: false
    property bool timerAlarmMode: false
    property real timerAlarmMinutes: 0.0

    property alias backgroundImage: background
    property alias centerImage: center

    property alias alarmIndicator: alarmIndicator

    property alias hourHandPxm: hourHand
    property alias hourHandCnv: hourHandCanvas
    property alias minuteHandPxm: minuteHand
    property alias minuteHandCnv: minuteHandCanvas
    property alias secondHandPxm: secondHand
    property alias secondHandCnv: secondHandCanvas

    Item {
        id: square

        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        width: Math.min(root.width, root.height)
        height: width

        property bool smallScale: square.width < maxSizeForCanvasItems

        Image {
            id: background
            anchors.fill: parent
            source: "content/background.png"
        }

        AlarmIndicator {
            id: alarmIndicator
            anchors.fill: parent
            opacity: 0.6
            minutesTime: timerAlarmMinutes
            armed: timerAlarmMode
        }

        CanvasHand {
            id: hourHandCanvas
            visible: square.smallScale
            tick: hourHand.tick
            anchors.fill: parent

            color: "#E9E7E6"
            outlineDarkerFactor: 1.4

            marginRatio: hourHand.marginRatio
            tailRatio: hourHand.tailRatio

            widthToRadiusRatio: 0.12
            topCapHeightToRadiusRatio: 0.0125
            bottomCapHeightToRadiusRatio: 0.0125
        }

        PixmapHand {
            id: hourHand
            visible: !square.smallScale
            source: "content/hour.sci"
            marginRatio: 0.4
            tailRatio: 0.05
        }

        CanvasHand {
            id: minuteHandCanvas
            visible: square.smallScale
            tick: minuteHand.tick
            anchors.fill: parent

            color: "#E9E7E6"
            outlineDarkerFactor: 1.4

            marginRatio: minuteHand.marginRatio
            tailRatio: minuteHand.tailRatio

            widthToRadiusRatio: 0.07
            topCapHeightToRadiusRatio: 0.015
            bottomCapHeightToRadiusRatio: 0.0125
        }

        PixmapHand {
            id: minuteHand
            visible: !square.smallScale
            source: "content/minute.sci"
            tailRatio: 0.05
        }

        CanvasHand {
            id: secondHandCanvas
            visible: secondHandVisible && square.smallScale
            anchors.fill: parent
            tick: secondHand.tick

            color: "#A92816"
            outlineDarkerFactor: 1.4

            marginRatio: secondHand.marginRatio
            tailRatio: secondHand.tailRatio

            widthToRadiusRatio: 0.018
            topCapHeightToRadiusRatio: 0.0125
            bottomCapHeightToRadiusRatio: 0.0125
        }

        PixmapHand {
            id: secondHand //cheap!
            visible: secondHandVisible && !square.smallScale
            source: "content/second.sci"
            tailRatio: 0.08
//            onTickChanged: console.log("sec: " + (new Date).getTime())
        }

        Image {
            id: center
            anchors.centerIn: parent
            scale: square.width/maxSizeForCanvasItems
            source: "content/center.png"
        }

        MouseArea {
            id: area
            anchors.fill: parent
            hoverEnabled: true
            acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
            onDoubleClicked: timerMode = !timerMode
            onClicked: {
                if (mouse.button === Qt.LeftButton)
                    timerPaused = !timerPaused
                else if (mouse.button === Qt.RightButton)
                    secondHandVisible = !secondHandVisible
                else //Qt.MiddleButton
                    timerAlarmMode = !timerAlarmMode
            }
            onWheel: {
                if (timerAlarmMode)
                    return

                //as per http://doc-snapshot.qt-project.org/5.0/qml-qtquick2-wheelevent.html
                var unitsPerClick = 120

                var delta = wheel.angleDelta.y / unitsPerClick
//                console.log("wheel, delta: " + delta)

                var minutes = Math.floor(timerAlarmMinutes)

                if (delta < 0) //rotated down
                    minutes -= 5.0*delta //5 minute step
                else
                    minutes -= delta //1 minute step

                if ((minutes >= 59.5) && (minutes <= 60.5))
                    timerAlarmMinutes = 60.0
                else
                    timerAlarmMinutes = Math.max(0.0, minutes) % 60

//                console.log("timerAlarmMinutes: " + timerAlarmMinutes)
            }
        }

        NumberAnimation {
            id: alarmAnimation
            target: square; property: "opacity"
            duration: 200
            from: 1.0; to: 0.75
            easing.type: Easing.InOutQuad
            loops: Animation.Infinite
            running: d.alarmFired
            onRunningChanged: {
                if (!running)
                    square.opacity = 1.0
            }
        }
    }

    Timer {
        interval: 250
        running: true
        repeat: true

        onTriggered: d.setTicks()
    }

    QtObject {
        id: d

        property variant timerStartTime
        property variant timerPauseStartTime
        property int timerPauseTotalTime: 0 //using variant here turns value into NaN on assignment
                                            //(Qt5 beta 1, Ubuntu Linux 32 bit, .run file "distro")

        property bool alarmFired: false

        function setTicksToCurrentTime() {
            var date = new Date
            var hours = date.getHours()
            var minutes = date.getMinutes()
            var seconds = date.getSeconds()

            hourHand.tick = (hours + minutes/60.0)*5
            minuteHand.tick = minutes + seconds/60.0
            secondHand.tick = seconds
        }

        function timerTotalTime() {
            return (new Date).getTime() - timerStartTime - timerPauseTotalTime
        }

        function setTicksToTimer() {
            if (timerPaused)
                return

            var timeDelta = timerTotalTime()
            var seconds = (timeDelta/1000) >> 0
            var minutes = (seconds/60) >> 0
            var hours = (minutes/60) >> 0

            secondHand.tick = seconds%60
            minuteHand.tick = (minutes%60)
            hourHand.tick = (hours%12)*5

//            console.log("timer: " + (new Date).getTime()
//                        + ", delta: " + timeDelta
//                        + ", timerStartTime: " + timerStartTime
//                        + ", timerPauseTotalTime: " + timerPauseTotalTime)
        }

        function alarmTimeOrLater() {
            return (timerAlarmMinutes > 0.0) && (timerAlarmMinutes < d.timerTotalTime()/1000/60)
        }

        function setTicks() {
            if (timerMode) {
                if (timerAlarmMode && !timerPaused
                        && alarmTimeOrLater()
                        && !alarmFired)
                {
                    alarm()
                    alarmFired = true
                }

                setTicksToTimer()
            } else {
                setTicksToCurrentTime()
            }
        }
    }

    onTimerModeChanged: {
        d.alarmFired = false

        if (timerMode) {
//            console.log("-timerMode: " + (new Date).getTime()
//                        + ", d.timerStartTime: " + d.timerStartTime
//                        + ", d.timerPauseTotalTime: " + d.timerPauseTotalTime)

            d.timerStartTime = (new Date).getTime()
            d.timerPauseTotalTime = 0
            timerPaused = false

//            console.log("+timerMode: " + (new Date).getTime()
//                        + ", d.timerStartTime: " + d.timerStartTime
//                        + ", d.timerPauseTotalTime: " + d.timerPauseTotalTime)
        }

        d.setTicks()
    }

    onTimerPausedChanged: {
        if (!timerMode)
            return

        if (timerPaused) {
            d.timerPauseStartTime = (new Date).getTime()
        } else {
            var pauseDelta = (new Date).getTime() - d.timerPauseStartTime
            d.timerPauseTotalTime += pauseDelta
        }

        d.setTicks()
    }

    Component.onCompleted: {
        d.setTicks()
    }
}
